﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKArchUtils.Utils;
using YJKRevitDimensionText.OneKeyPlanDim.Utility;

namespace YJKRevitDimensionText.OneKeyPlanDim.DimData
{
	public class DbRevitRamp : DbDimBase
	{
		public DbRevitRamp(Element ramp)
		{
			this.m_Ramp = ramp;
		}

		public Line SlopeStartLine
		{
			get
			{
				this.AnalysisInfo();
				return this.m_SlopeStartLine;
			}
		}

		public XYZ CenterPoint
		{
			get
			{
				if (!this.AnalysisInfo())
				{
					return XYZ.Zero;
				}
				return GeometryHelper.GeometricCenterOfPlanarFace(this.m_StartBasePlanarFace);
			}
		}

		public bool AnalysisInfo()
		{
			if (!base.IsNeedAnalysisInfo())
			{
				return true;
			}
			try
			{
				if (!this.GetStartBasePlanarFace())
				{
					return false;
				}
				this.GetSlopeUpDir();
				this.CalSlopeValue();
				List<CurveLoop> list = new List<CurveLoop>();
				foreach (CurveLoop curveLoop in this.m_StartBasePlanarFace.GetEdgesAsCurveLoops())
				{
					CurveLoop xyplaneCurve = CommonInterface.GetXYPlaneCurve(curveLoop);
					list.Add(xyplaneCurve);
				}
				OcclusionArea.GetInstance().AddRampCurve(this.m_Ramp.Id, list);
			}
			catch
			{
				return false;
			}
			return !(this.m_SlopeStartLine == null);
		}

		public override bool CreateSizeDim(Autodesk.Revit.DB.Document doc)
		{
			return base.CreateSizeDim(doc) && this.AnalysisInfo();
		}

		public override bool CreateLevelDim(Autodesk.Revit.DB.Document doc, out List<SingleLevelDimDataInfo> lstSingleLevelDimDataInfo)
		{
			if (!base.CreateLevelDim(doc, out lstSingleLevelDimDataInfo))
			{
				return false;
			}
			if (!this.AnalysisInfo())
			{
				return false;
			}
			XYZ xyz = (this.SlopeStartLine.GetEndPoint(0) + this.SlopeStartLine.GetEndPoint(1)) / 2.0 - this.m_SlopeDimDir * (Common.MMToFeet(1500.0) * (double)this.m_doc.ActiveView.Scale / 100.0);
			if (base.ComponentInSlopePlanarFace != null)
			{
				xyz = CommonInterface.PtInPlanarFaceInDir(xyz, base.ComponentInSlopePlanarFace, XYZ.BasisZ);
			}
			FamilyInstance familyInstance = new LevelDimData(this.m_doc)
			{
				PtDimLocation = xyz,
				DimVal = base.FloorLevelVal
			}.CreateLevelDim();
			AnnotationSymbol annotationSymbol = null;
			if (familyInstance != null)
			{
				annotationSymbol = (familyInstance as AnnotationSymbol);
			}
			if (annotationSymbol != null)
			{
				SingleLevelDimDataInfo singleLevelDimDataInfo = new SingleLevelDimDataInfo(annotationSymbol);
				if (base.ComponentInSlopePlanarFace != null)
				{
					singleLevelDimDataInfo.LevelVal = xyz.Z;
				}
				else
				{
					singleLevelDimDataInfo.LevelVal = base.dFloorLevelVal;
				}
				singleLevelDimDataInfo.LadderLineLength = this.SlopeStartLine.Length;
				singleLevelDimDataInfo.DimDir = this.SlopeStartLine.Direction;
				singleLevelDimDataInfo.PtLocation = xyz;
				singleLevelDimDataInfo.bStepDownDim = false;
				singleLevelDimDataInfo.m_LstElementId.Add(this.m_Ramp.Id);
				lstSingleLevelDimDataInfo.Add(singleLevelDimDataInfo);
			}
			return true;
		}

		public override bool CreateSlopeDim(Autodesk.Revit.DB.Document doc)
		{
			if (!base.CreateSlopeDim(doc))
			{
				return false;
			}
			if (!this.AnalysisInfo())
			{
				return false;
			}
			if (this.m_SlopeStartLine == null || this.m_SlopeStartLine == null)
			{
				return false;
			}
			XYZ ptStart = (this.m_SlopeStartLine.GetEndPoint(0) + this.m_SlopeStartLine.GetEndPoint(1)) / 2.0;
			FamilyInstance familyInstance = new SlopeDimData(this.m_doc)
			{
				PtStart = ptStart,
				SlopeDimDir = this.m_SlopeDimDir,
				DimVal = this.m_strSlopeValue
			}.CreateSlopeDim();
			if (familyInstance == null)
			{
				return false;
			}
			base.SetSlopeOcclusionArea(familyInstance);
			return true;
		}

		private bool GetStartBasePlanarFace()
		{
			List<Line> list = new List<Line>();
			foreach (Curve curve in GeometryHelper.GetAllEdgeList(this.m_Ramp))
			{
				Line line = curve as Line;
				if (line != null && GeometryHelper.VectorVerticalVector(line.Direction, XYZ.BasisZ))
				{
					list.Add(line);
				}
			}
			this.m_SlopeStartLine = null;
			double num = double.MaxValue;
			foreach (Line line2 in list)
			{
				double num2 = Geometry.LessThan(line2.GetEndPoint(0).Z, line2.GetEndPoint(1).Z) ? line2.GetEndPoint(1).Z : line2.GetEndPoint(0).Z;
				if (Geometry.LessThan(num2, num))
				{
					num = num2;
					this.m_SlopeStartLine = line2;
				}
			}
			if (this.m_SlopeStartLine == null)
			{
				return false;
			}
			List<PlanarFace> list2 = GeometryHelper.PlanarFaceWithCommonLine(GeometryHelper.GetAllPlanarFace(this.m_Ramp), this.m_SlopeStartLine);
			if (list2.Count != 2)
			{
				return false;
			}
			this.m_StartBasePlanarFace = ((list2[0].Area > list2[1].Area) ? list2[0] : list2[1]);
			return true;
		}

		private void GetSlopeUpDir()
		{
			XYZ xyz = (this.m_SlopeStartLine.GetEndPoint(0) + this.m_SlopeStartLine.GetEndPoint(1)) / 2.0;
			XYZ xyz2 = XYZ.BasisZ.CrossProduct(this.m_SlopeStartLine.Direction).Normalize();
			xyz2 = new XYZ(xyz2.X, xyz2.Y, 0.0);
			this.m_SlopeDimDir = xyz2.Normalize();
			XYZ xyz3 = xyz + this.m_SlopeDimDir * Common.MMToFeet(100.0);
			XYZ xyz4 = xyz - this.m_SlopeDimDir * Common.MMToFeet(100.0);
			xyz = GeometryHelper.GeometricCenterOfPlanarFace(this.m_StartBasePlanarFace);
			if (Geometry.LessThan(xyz4.DistanceTo(xyz), xyz3.DistanceTo(xyz)))
			{
				this.m_SlopeDimDir = -this.m_SlopeDimDir;
			}
		}

		private void CalSlopeValue()
		{
			double num = this.m_StartBasePlanarFace.FaceNormal.AngleTo(XYZ.BasisZ);
			if (Geometry.LessThan(Math.PI*.5, num))
			{
				num = Math.PI - num;
			}
			double num2 = 1.0 / Math.Tan(num);
			int num3 = (int)num2;
			if (Geometry.IsEqual(num2, (double)num3))
			{
				this.m_strSlopeValue = num3.ToString();
			}
			else
			{
				this.m_strSlopeValue = num2.ToString("f2");
			}
			this.m_strSlopeValue = "1 : " + this.m_strSlopeValue;
		}

		private Element m_Ramp;

		private PlanarFace m_StartBasePlanarFace;

		private Line m_SlopeStartLine;

		private string m_strSlopeValue = string.Empty;

		private XYZ m_SlopeDimDir = XYZ.Zero;
	}
}
